package by.bsu.fpmi.bbtp.impl;

import by.bsu.fpmi.bbtp.controllers.OrderController;
import by.bsu.fpmi.bbtp.dao.ClientDAO;
import by.bsu.fpmi.bbtp.dao.OrderDAO;
import by.bsu.fpmi.bbtp.entities.Client;
import by.bsu.fpmi.bbtp.entities.Order;
import by.bsu.fpmi.bbtp.entities.OrderHead;
import org.objectweb.asm.Type;
import org.springframework.beans.factory.annotation.Autowired;

import javax.jws.WebParam;
import javax.jws.WebService;
import java.util.ArrayList;
import java.util.List;

@WebService(endpointInterface = "by.bsu.fpmi.bbtp.controllers.OrderController")
public class OrderControllerImpl implements OrderController {

    @Autowired
    private OrderDAO orderDao;
    @Autowired
    private ClientDAO clientDao;

    @Override
    public void cancelOrder(String sessionId, long orderId) {
        Order order = orderDao.find(orderId);
        orderDao.remove(order);
    }

    @Override
    public void saveOrder(String sessionId, Order order) {
        orderDao.save(order);
    }

    @Override
    public void createOrder(String sessionId, Order order, Client client) {
        createOrder(order, client, Order.Type.ORDINARY);
    }

    @Override
    public void createOrderForReturn(String sessionId, long orderId) {
        Order order = orderDao.find(orderId);
        order.setType(Order.Type.FOR_RETURN);
        order.setState(Order.State.CREATED);
        orderDao.save(order);
    }

    @Override
    public List<OrderHead> getAllOrders(String sessionId) {
        return getHeads(orderDao.all());
    }

    @Override
    public List<OrderHead> getOrdersForReturn(String sessionId) {
        List<Order> orders = filterByType(orderDao.all(), Order.Type.FOR_RETURN);
        orders = filterByState(orders, Order.State.CREATED);
        return getHeads(orders);
    }

    @Override
    public List<OrderHead> getReadyOrders(String sessionId) {
        List<Order> orders = filterByState(orderDao.all(), Order.State.CREATED);
        orders = filterByType(orders, Order.Type.ORDINARY);
        return getHeads(orders);
    }

    @Override
    public List<OrderHead> getSentOrders(String sessionId) {
        List<Order> orders = filterByState(orderDao.all(), Order.State.SENT_TO_CLIENT);
        orders = filterByType(orders, Order.Type.ORDINARY);
        return getHeads(orders);
    }

    @Override
    public Order getOrder(String sessionId, long orderId) {
        return orderDao.find(orderId);
    }

    @Override
    public void setTransportCompanyForOrder(String sessionId, long orderId, long transportCompanyId) {
        Order order = orderDao.find(orderId);
        order.setTransportCompanyId(transportCompanyId);
        order.setState(Order.State.SENT_TO_CLIENT);
        orderDao.save(order);
    }

    private List<OrderHead> getHeads(List<Order> orders) {
        List<OrderHead> heads = new ArrayList<OrderHead>();
        for (Order order : orders) {
            heads.add(order.getHead());
        }
        return heads;
    }
    
    private List<Order> filterByType(List<Order> orders, Order.Type type) {
        List<Order> result = new ArrayList<Order>();
        for (Order order : orders) {
            if (order.getType() == type) {
                result.add(order);
            }
        }
        return result;
    }

    private List<Order> filterByState(List<Order> orders, Order.State state) {
        List<Order> result = new ArrayList<Order>();
        for (Order order : orders) {
            if (order.getState() == state) {
                result.add(order);
            }
        }
        return result;
    }

    private void createOrder(Order order, Client client, Order.Type type) {
        clientDao.save(client);
        order.setClientId(client.getId());
        order.setType(type);
        order.setState(Order.State.CREATED);
        orderDao.save(order);
    }
}
